package moodish.server;


import java.util.ArrayList;
import java.util.LinkedList;

import moodish.comm.MoodishServerComm;
import moodish.comm.MoodishServerSideMessage;
import moodish.comm.ServerComm;
import moodish.server.MoodishServer;

/**
 * The server that:  keep track of who follows who and forward Mood messages accordingly; 
 * keep clients informed about who friends and unfriends them;
 * when a new client connects, the server send the list of currently connected user to that client so that the client will have an updated list of all currently connected users;
 * when a client connects or disconnects, the server sends a message with the appropriate information to all connected clients
 * @author Joao / Ricardo
 *
 */



public class ServerMain implements MoodishServer {


        private ArrayList<User> listOfUsers = new ArrayList<User>();
        @Override
        public void start(MoodishServerComm serverComm) {
            
                serverComm.start();
                while (true) {

                        if (serverComm.hasNextMessage()){

                                MoodishServerSideMessage message = (MoodishServerSideMessage) serverComm.getNextMessage();


                                /**
                                 * When a client connects, the server send one {@link moodish.comm.ClientSideMessage.Type#CONNECTED CONNECTED} message 
                                 * ({@link moodish.comm.ServerComm#sendClientConnected(String toNickname, String connectedNickname)
                                 * ServerComm.sendClientConnected()}) for each connected client so that the newly connected client can maintain a list 
                                 * of clients currently connected to the server. 
                                 */

                                if (message.getType() == MoodishServerSideMessage.Type.CLIENT_CONNECTED){
                                        System.out.println("O servidor recebeu uma mensagem do tipo: " + message.getType());
                                        boolean tempIsRegisteredUser = false;

                                        User newUser = new User(message.getClientNickname());
                                        newUser.setConnected();



                                        // 1) Warn every one that there is a new client 
                                        // 2) And send the list of online users to the new client


                                        for(User user : listOfUsers){
                                                System.out.println( user.getUser());
                                                serverComm.sendClientConnected(user.getUser(), newUser.getUser());
                                                serverComm.sendClientConnected(newUser.getUser(), user.getUser());
                                        }
                                        listOfUsers.add(newUser);
                                }

                                /**
                                 * 
                                 *<p>
                                 * When a client disconnects, all clients should be sent a {@link moodish.comm.ClientSideMessage.Type#DISCONNECTED DISCONNECTED} message 
                                 * ({@link moodish.comm.ServerComm#sendClientDisconnected(String toNickname, String disconnectedNickname)
                                 * ServerComm.sendClientDisconnected()}). When a client disconnects, it loses all its friends and automatically
                                 * unfriends all other clients. The server should thus not maintain a memory server regarding friends of disconnected clients. 
                                 */

                                //checks if the message is type CLIENT_DISCONNECTED
                                else if (message.getType() == MoodishServerSideMessage.Type.CLIENT_DISCONNECTED){
                                        System.out.println("O servidor recebeu uma mensagem do tipo: " + message.getType());
                                        User userLeaving = null;
                                        for(User user: listOfUsers){
                                                if(user.getUser().equals(message.getClientNickname()))
                                                        userLeaving = user;
                                        }

                                        listOfUsers.remove(userLeaving);

                                        for(User user: listOfUsers){
                                                serverComm.sendClientDisconnected(user.getUser(), userLeaving.getUser());
                                        }
                                }

                                //checks if the message is type MOODISH_MESSAGE
                                else if (message.getType().equals(MoodishServerSideMessage.Type.MOODISH_MESSAGE)) {
                                        System.out.println("O servidor recebeu uma mensagem do tipo: " + message.getType());
                                        LinkedList<String> tempFriends = new LinkedList<String>();


                                        //search in list of User
                                        for (User user: listOfUsers){
                                                //search in friendsList
                                                for( String friendUser : user.getlistOffriends()) {
                                                        //if the sender exists in the friendsList send the mood
                                                        if(friendUser.equals(message.getClientNickname())){
                                                                serverComm.sendMoodishMessage(message.getClientNickname(),  user.getUser(), message.getPayload());
                                                        }
                                                }
                                        }
                                }

                                //checks if the message is type FRIENDSHIP
                                else if (message.getType().equals(MoodishServerSideMessage.Type.FRIENDSHIP)){
                                        System.out.println("O servidor recebeu uma mensagem do tipo: " + message.getType());
                                        for (User user: listOfUsers){
                                                if (user.getUser().equals(message.getClientNickname())){

                                                        //If not in his list of Following, it add him to the list and sends a sendNewFollowers message.
                                                        if (!user.inTheListofFriends(message.getPayload())){ 

                                                                user.addfriend(message.getPayload());
                                                                serverComm.sendNewFriendship(message.getPayload(), message.getClientNickname());
                                                        }
                                                        else
                                                                //if in the list, it sends one error message
                                                                serverComm.sendError(message.getClientNickname(), "Already following the requested user");

                                                }
                                        }
                                }

                                //checks if the message is type UNFRIENDSHIP
                                else if (message.getType() == MoodishServerSideMessage.Type.UNFREINDSHIP){
                                        System.out.println("O servidor recebeu uma mensagem do tipo: " + message.getType());

                                        for (User user: listOfUsers){
                                                if (user.getUser().equals(message.getClientNickname())){
                                                        //If is in the list of users he his following, it removes and sends a message sendNewUnfollow
                                                        if(user.inTheListofFriends(message.getPayload())){
                                                                user.removeFriend(message.getPayload());
                                                                serverComm.sendNewUnfriendship(message.getPayload(), message.getClientNickname());
                                                        }
                                                        else
                                                                //Of not in the list, sends one error message
                                                                serverComm.sendError(message.getClientNickname(), "Not following the requested user");
                                                }

                                        }

                                }
                                else {
                                        //If it sends one message that has no Type than the others, it sends one error message
                                        serverComm.sendError(message.getClientNickname(), "Erro - servico solicitado nao existente!!!!");
                                }
                        }
                }
        }

	

}

